package com.dream.root.common.jwt;

import com.dream.root.common.constants.CommonConstants;
import com.dream.root.common.exception.BaseException;
import com.dream.root.common.response.BaseResponseCode;
import com.dream.root.entity.dto.TokenDataDto;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

/**
 * JWTHelper Created with IntelliJ IDEA.
 * User: liulinhui
 * Date: 29/07/2018
 * Time: 18:46
 * Description: JWTHelper
 */
public class JWTHelper {
    private static RsaKeyHelper rsaKeyHelper = new RsaKeyHelper();

    /**
     * 生成token
     *
     * @param tokenData  token元数据
     * @param priKeyPath 私钥文件路径
     * @return String
     */
    public static String generateToken(TokenDataDto tokenData, String priKeyPath) {
        String token = "";
        try {
            token = Jwts.builder()
                    .claim(CommonConstants.JWT_KEY_CREATED, tokenData.getT())
                    .claim(CommonConstants.JWT_KEY_USER_ID, tokenData.getId())
                    .claim(CommonConstants.JWT_KEY_REFRESH, tokenData.getV())
                    .signWith(SignatureAlgorithm.RS256, rsaKeyHelper.getPrivateKey(priKeyPath))
                    .compact();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BaseResponseCode.TOKEN_FAIL_CREATE, e);
        }
        return token;
    }

    /**
     * 公钥解析token
     *
     * @param token token
     * @return
     */
    private static Jws<Claims> parserToken(String token, String pubKeyPath) {
        try {
            return Jwts.parser().setSigningKey(rsaKeyHelper.getPublicKey(pubKeyPath)).parseClaimsJws(token);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BaseResponseCode.TOKEN_INVALID, e);
        }
    }

    /**
     * 获取token中的信息
     *
     * @param token      token
     * @param pubKeyPath 公钥地址
     * @return TokenData
     */
    public static TokenDataDto getInfoFromToken(String token, String pubKeyPath) {
        Jws<Claims> claimsJws = parserToken(token, pubKeyPath);
        Claims body = claimsJws.getBody();
        return TokenDataDto
                .builder()
                .id(Long.valueOf(getObjectValue(body.get(CommonConstants.JWT_KEY_CREATED))))
                .t(Long.valueOf(getObjectValue(body.get(CommonConstants.JWT_KEY_CREATED))))
                .v(Long.valueOf(getObjectValue(body.get(CommonConstants.JWT_KEY_REFRESH))))
                .build();
    }

    /**
     * object 转 String
     *
     * @param obj obj
     * @return String
     */
    private static String getObjectValue(Object obj) {
        return obj == null ? "" : obj.toString();
    }

}
